mirror of
https://github.com/exoticorn/curlywas.git
synced 2026-01-20 11:46:43 +01:00
implement const
This commit is contained in:
@@ -1,29 +1,8 @@
|
|||||||
import "env.memory" memory(4);
|
include "uw8.cwa"
|
||||||
|
|
||||||
import "env.pow" fn pow(f32, f32) -> f32;
|
const SWEETY = PALETTE + 192 * 4;
|
||||||
import "env.sin" fn sin(f32) -> f32;
|
|
||||||
import "env.cos" fn cos(f32) -> f32;
|
|
||||||
import "env.atan2" fn atan2(f32, f32) -> f32;
|
|
||||||
import "env.tan" fn tan(f32) -> f32;
|
|
||||||
import "env.atan" fn atan(f32) -> f32;
|
|
||||||
import "env.rectangle" fn rect(f32, f32, f32, f32, i32);
|
|
||||||
|
|
||||||
//export fn tic(time: i32) {
|
export fn upd() {
|
||||||
// let i: i32;
|
|
||||||
// loop pixels {
|
|
||||||
// let lazy x = (i % 320) as f32 - 160.5;
|
|
||||||
// let lazy y = (i / 320 - 120) as f32;
|
|
||||||
//
|
|
||||||
// let lazy dist = 4000 as f32 / sqrt(x*x + y*y + 10 as f32);
|
|
||||||
// let lazy angle = atan2(x, y) * (64.0 / 3.141);
|
|
||||||
//
|
|
||||||
// i?120 = ((((dist + time as f32 / 63 as f32) as i32 ^ angle as i32) #% 32 + 32) >> ((dist as i32 - i % 7 * 3) / 40)) + 192;
|
|
||||||
//
|
|
||||||
// branch_if (i := i + 1) < 320*240: pixels;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
export fn tic(time: i32) {
|
|
||||||
let i: i32;
|
let i: i32;
|
||||||
loop colors {
|
loop colors {
|
||||||
rect((i % 16 * 15) as f32, (i / 16 * 15) as f32, 15 as f32, 15 as f32, i);
|
rect((i % 16 * 15) as f32, (i / 16 * 15) as f32, 15 as f32, 15 as f32, i);
|
||||||
@@ -43,7 +22,7 @@ start fn gen_palette() {
|
|||||||
let lazy a = max(llimit, min(ulimit, c)) * (scale + 0.05);
|
let lazy a = max(llimit, min(ulimit, c)) * (scale + 0.05);
|
||||||
let lazy b = scale * scale * 0.8;
|
let lazy b = scale * scale * 0.8;
|
||||||
let inline v = (select(i < 11*16*3, max(0 as f32, min(a + b - a * b, 1 as f32)), scale) * 255 as f32) as i32;
|
let inline v = (select(i < 11*16*3, max(0 as f32, min(a + b - a * b, 1 as f32)), scale) * 255 as f32) as i32;
|
||||||
(i%3 + i/3*4)?(120+320*240) = v;
|
(i%3 + i/3*4)?(PALETTE) = v;
|
||||||
avg = (avg + c) * 0.5;
|
avg = (avg + c) * 0.5;
|
||||||
|
|
||||||
branch_if i := i - 1: gradients;
|
branch_if i := i - 1: gradients;
|
||||||
@@ -56,15 +35,15 @@ start fn gen_palette() {
|
|||||||
let lazy first_step = index >= 32;
|
let lazy first_step = index >= 32;
|
||||||
let inline src1 = select(first_step, index % 32 / 2, index * 2);
|
let inline src1 = select(first_step, index % 32 / 2, index * 2);
|
||||||
let inline src2 = select(first_step, (index + 1) % 32 / 2, index * 2 + 1);
|
let inline src2 = select(first_step, (index + 1) % 32 / 2, index * 2 + 1);
|
||||||
let inline c1 = (src1 * 4 + channel)?(120+320*240+192*4);
|
let inline c1 = (src1 * 4 + channel)?SWEETY;
|
||||||
let inline c2 = (src2 * 4 + channel)?(120+320*240+192*4);
|
let inline c2 = (src2 * 4 + channel)?SWEETY;
|
||||||
i?(120+320*240+192*4) = (c1 + c2) * (3 + first_step) / 8;
|
i?(SWEETY) = (c1 + c2) * (3 + first_step) / 8;
|
||||||
|
|
||||||
branch_if (i := i - 1) >= 0: expand_sweetie;
|
branch_if (i := i - 1) >= 0: expand_sweetie;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data 120+320*240+192*4 {
|
data SWEETY {
|
||||||
i32(
|
i32(
|
||||||
0x2c1c1a,
|
0x2c1c1a,
|
||||||
0x5d275d,
|
0x5d275d,
|
||||||
|
|||||||
13
examples/microw8/uw8.cwa
Normal file
13
examples/microw8/uw8.cwa
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import "env.memory" memory(4);
|
||||||
|
|
||||||
|
import "env.pow" fn pow(f32, f32) -> f32;
|
||||||
|
import "env.sin" fn sin(f32) -> f32;
|
||||||
|
import "env.cos" fn cos(f32) -> f32;
|
||||||
|
import "env.atan2" fn atan2(f32, f32) -> f32;
|
||||||
|
import "env.tan" fn tan(f32) -> f32;
|
||||||
|
import "env.atan" fn atan(f32) -> f32;
|
||||||
|
import "env.rectangle" fn rect(f32, f32, f32, f32, i32);
|
||||||
|
|
||||||
|
const FRAMEBUFFER = 120;
|
||||||
|
const PALETTE = 0x13000;
|
||||||
|
const FONT = 0x13400;
|
||||||
30
src/ast.rs
30
src/ast.rs
@@ -8,7 +8,8 @@ pub struct Script {
|
|||||||
pub global_vars: Vec<GlobalVar>,
|
pub global_vars: Vec<GlobalVar>,
|
||||||
pub functions: Vec<Function>,
|
pub functions: Vec<Function>,
|
||||||
pub data: Vec<Data>,
|
pub data: Vec<Data>,
|
||||||
pub includes: Vec<Include>
|
pub includes: Vec<Include>,
|
||||||
|
pub consts: Vec<GlobalConst>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Script {
|
impl Script {
|
||||||
@@ -17,6 +18,7 @@ impl Script {
|
|||||||
self.global_vars.append(&mut other.global_vars);
|
self.global_vars.append(&mut other.global_vars);
|
||||||
self.functions.append(&mut other.functions);
|
self.functions.append(&mut other.functions);
|
||||||
self.data.append(&mut other.data);
|
self.data.append(&mut other.data);
|
||||||
|
self.consts.append(&mut other.consts);
|
||||||
assert!(other.includes.is_empty());
|
assert!(other.includes.is_empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,7 +29,8 @@ pub enum TopLevelItem {
|
|||||||
GlobalVar(GlobalVar),
|
GlobalVar(GlobalVar),
|
||||||
Function(Function),
|
Function(Function),
|
||||||
Data(Data),
|
Data(Data),
|
||||||
Include(Include)
|
Include(Include),
|
||||||
|
Const(GlobalConst),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -67,6 +70,14 @@ pub struct GlobalVar {
|
|||||||
pub mutable: bool,
|
pub mutable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GlobalConst {
|
||||||
|
pub span: Span,
|
||||||
|
pub name: String,
|
||||||
|
pub value: Expression,
|
||||||
|
pub type_: Option<Type>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
@@ -170,7 +181,7 @@ pub enum DataType {
|
|||||||
F64,
|
F64,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct MemoryLocation {
|
pub struct MemoryLocation {
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub size: MemSize,
|
pub size: MemSize,
|
||||||
@@ -178,7 +189,7 @@ pub struct MemoryLocation {
|
|||||||
pub right: Box<Expression>,
|
pub right: Box<Expression>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Expression {
|
pub struct Expression {
|
||||||
pub type_: Option<Type>,
|
pub type_: Option<Type>,
|
||||||
pub expr: Expr,
|
pub expr: Expr,
|
||||||
@@ -213,9 +224,16 @@ impl Expression {
|
|||||||
_ => panic!("Expected F64Const"),
|
_ => panic!("Expected F64Const"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_const(&self) -> bool {
|
||||||
|
match self.expr {
|
||||||
|
Expr::I32Const(_) | Expr::I64Const(_) | Expr::F32Const(_) | Expr::F64Const(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Expr {
|
pub enum Expr {
|
||||||
Block {
|
Block {
|
||||||
statements: Vec<Expression>,
|
statements: Vec<Expression>,
|
||||||
@@ -355,7 +373,7 @@ pub enum BinOp {
|
|||||||
pub enum MemSize {
|
pub enum MemSize {
|
||||||
Byte,
|
Byte,
|
||||||
Word,
|
Word,
|
||||||
Float
|
Float,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
|
||||||
|
|||||||
146
src/constfold.rs
146
src/constfold.rs
@@ -1,35 +1,103 @@
|
|||||||
use crate::ast;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
ast,
|
||||||
|
parser::{Sources, Span},
|
||||||
|
typecheck::{report_duplicate_definition, report_error},
|
||||||
|
};
|
||||||
|
|
||||||
|
type Result<T> = std::result::Result<T, ()>;
|
||||||
|
|
||||||
|
pub fn fold_script(script: &mut ast::Script, sources: &Sources) -> Result<()> {
|
||||||
|
let mut context = Context {
|
||||||
|
consts: HashMap::new(),
|
||||||
|
sources,
|
||||||
|
};
|
||||||
|
fold_consts(&mut context, &mut script.consts)?;
|
||||||
|
|
||||||
pub fn fold_script(script: &mut ast::Script) {
|
|
||||||
for var in &mut script.global_vars {
|
for var in &mut script.global_vars {
|
||||||
fold_expr(&mut var.value);
|
fold_expr(&context, &mut var.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
for func in &mut script.functions {
|
for func in &mut script.functions {
|
||||||
fold_expr(&mut func.body);
|
fold_expr(&context, &mut func.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
for data in &mut script.data {
|
for data in &mut script.data {
|
||||||
fold_expr(&mut data.offset);
|
fold_expr(&context, &mut data.offset);
|
||||||
for values in &mut data.data {
|
for values in &mut data.data {
|
||||||
match values {
|
match values {
|
||||||
ast::DataValues::Array { values, .. } => {
|
ast::DataValues::Array { values, .. } => {
|
||||||
for value in values {
|
for value in values {
|
||||||
fold_expr(value);
|
fold_expr(&context, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::DataValues::String(_) | ast::DataValues::File { .. } => (),
|
ast::DataValues::String(_) | ast::DataValues::File { .. } => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_mem_location(mem_location: &mut ast::MemoryLocation) {
|
struct Context<'a> {
|
||||||
fold_expr(&mut mem_location.left);
|
consts: HashMap<String, ast::Expr>,
|
||||||
fold_expr(&mut mem_location.right);
|
sources: &'a Sources,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_expr(expr: &mut ast::Expression) {
|
fn fold_consts(context: &mut Context, consts: &mut [ast::GlobalConst]) -> Result<()> {
|
||||||
|
let mut spans: HashMap<&str, Span> = HashMap::new();
|
||||||
|
|
||||||
|
for cnst in consts.iter_mut() {
|
||||||
|
if let Some(prev_span) = spans.insert(&cnst.name, cnst.span.clone()) {
|
||||||
|
report_duplicate_definition(
|
||||||
|
"Const already defined",
|
||||||
|
&cnst.span,
|
||||||
|
&prev_span,
|
||||||
|
context.sources,
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while context.consts.len() < consts.len() {
|
||||||
|
let mut making_progress = false;
|
||||||
|
for cnst in consts.iter_mut() {
|
||||||
|
if !context.consts.contains_key(&cnst.name) {
|
||||||
|
fold_expr(context, &mut cnst.value);
|
||||||
|
if cnst.value.is_const() {
|
||||||
|
context
|
||||||
|
.consts
|
||||||
|
.insert(cnst.name.clone(), cnst.value.expr.clone());
|
||||||
|
making_progress = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !making_progress {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut result = Ok(());
|
||||||
|
for cnst in consts {
|
||||||
|
if !context.consts.contains_key(&cnst.name) {
|
||||||
|
result = report_error(
|
||||||
|
&format!("Failed to fold const '{}'", cnst.name),
|
||||||
|
&cnst.span,
|
||||||
|
context.sources,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_mem_location(context: &Context, mem_location: &mut ast::MemoryLocation) {
|
||||||
|
fold_expr(context, &mut mem_location.left);
|
||||||
|
fold_expr(context, &mut mem_location.right);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fold_expr(context: &Context, expr: &mut ast::Expression) {
|
||||||
use ast::BinOp::*;
|
use ast::BinOp::*;
|
||||||
match expr.expr {
|
match expr.expr {
|
||||||
ast::Expr::Block {
|
ast::Expr::Block {
|
||||||
@@ -37,15 +105,15 @@ fn fold_expr(expr: &mut ast::Expression) {
|
|||||||
ref mut final_expression,
|
ref mut final_expression,
|
||||||
} => {
|
} => {
|
||||||
for stmt in statements {
|
for stmt in statements {
|
||||||
fold_expr(stmt);
|
fold_expr(context, stmt);
|
||||||
}
|
}
|
||||||
if let Some(ref mut expr) = final_expression {
|
if let Some(ref mut expr) = final_expression {
|
||||||
fold_expr(expr);
|
fold_expr(context, expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Expr::Let { ref mut value, .. } => {
|
ast::Expr::Let { ref mut value, .. } => {
|
||||||
if let Some(ref mut expr) = value {
|
if let Some(ref mut expr) = value {
|
||||||
fold_expr(expr);
|
fold_expr(context, expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Expr::Poke {
|
ast::Expr::Poke {
|
||||||
@@ -53,12 +121,12 @@ fn fold_expr(expr: &mut ast::Expression) {
|
|||||||
ref mut value,
|
ref mut value,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
fold_mem_location(mem_location);
|
fold_mem_location(context, mem_location);
|
||||||
fold_expr(value);
|
fold_expr(context, value);
|
||||||
}
|
}
|
||||||
ast::Expr::Peek(ref mut mem_location) => fold_mem_location(mem_location),
|
ast::Expr::Peek(ref mut mem_location) => fold_mem_location(context, mem_location),
|
||||||
ast::Expr::UnaryOp { op, ref mut value } => {
|
ast::Expr::UnaryOp { op, ref mut value } => {
|
||||||
fold_expr(value);
|
fold_expr(context, value);
|
||||||
let result = match (op, &value.expr) {
|
let result = match (op, &value.expr) {
|
||||||
(ast::UnaryOp::Negate, ast::Expr::I32Const(value)) => {
|
(ast::UnaryOp::Negate, ast::Expr::I32Const(value)) => {
|
||||||
Some(ast::Expr::I32Const(-*value))
|
Some(ast::Expr::I32Const(-*value))
|
||||||
@@ -90,8 +158,8 @@ fn fold_expr(expr: &mut ast::Expression) {
|
|||||||
ref mut right,
|
ref mut right,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
fold_expr(left);
|
fold_expr(context, left);
|
||||||
fold_expr(right);
|
fold_expr(context, right);
|
||||||
match (&left.expr, &right.expr) {
|
match (&left.expr, &right.expr) {
|
||||||
(&ast::Expr::I32Const(left), &ast::Expr::I32Const(right)) => {
|
(&ast::Expr::I32Const(left), &ast::Expr::I32Const(right)) => {
|
||||||
let result = match op {
|
let result = match op {
|
||||||
@@ -237,24 +305,28 @@ fn fold_expr(expr: &mut ast::Expression) {
|
|||||||
ast::Expr::I32Const(_)
|
ast::Expr::I32Const(_)
|
||||||
| ast::Expr::I64Const(_)
|
| ast::Expr::I64Const(_)
|
||||||
| ast::Expr::F32Const(_)
|
| ast::Expr::F32Const(_)
|
||||||
| ast::Expr::F64Const(_)
|
| ast::Expr::F64Const(_) => (),
|
||||||
| ast::Expr::Variable { .. } => (),
|
ast::Expr::Variable { ref name, .. } => {
|
||||||
ast::Expr::Assign { ref mut value, .. } => fold_expr(value),
|
if let Some(value) = context.consts.get(name) {
|
||||||
ast::Expr::LocalTee { ref mut value, .. } => fold_expr(value),
|
expr.expr = value.clone();
|
||||||
ast::Expr::Loop { ref mut block, .. } => fold_expr(block),
|
}
|
||||||
ast::Expr::LabelBlock { ref mut block, .. } => fold_expr(block),
|
}
|
||||||
|
ast::Expr::Assign { ref mut value, .. } => fold_expr(context, value),
|
||||||
|
ast::Expr::LocalTee { ref mut value, .. } => fold_expr(context, value),
|
||||||
|
ast::Expr::Loop { ref mut block, .. } => fold_expr(context, block),
|
||||||
|
ast::Expr::LabelBlock { ref mut block, .. } => fold_expr(context, block),
|
||||||
ast::Expr::Branch(_) => (),
|
ast::Expr::Branch(_) => (),
|
||||||
ast::Expr::BranchIf {
|
ast::Expr::BranchIf {
|
||||||
ref mut condition, ..
|
ref mut condition, ..
|
||||||
} => fold_expr(condition),
|
} => fold_expr(context, condition),
|
||||||
ast::Expr::Cast { ref mut value, .. } => fold_expr(value),
|
ast::Expr::Cast { ref mut value, .. } => fold_expr(context, value),
|
||||||
ast::Expr::FuncCall {
|
ast::Expr::FuncCall {
|
||||||
ref name,
|
ref name,
|
||||||
ref mut params,
|
ref mut params,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
for param in params.iter_mut() {
|
for param in params.iter_mut() {
|
||||||
fold_expr(param);
|
fold_expr(context, param);
|
||||||
}
|
}
|
||||||
use ast::Expr::*;
|
use ast::Expr::*;
|
||||||
let params: Vec<_> = params.iter().map(|e| &e.expr).collect();
|
let params: Vec<_> = params.iter().map(|e| &e.expr).collect();
|
||||||
@@ -269,31 +341,31 @@ fn fold_expr(expr: &mut ast::Expression) {
|
|||||||
ref mut if_false,
|
ref mut if_false,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
fold_expr(condition);
|
fold_expr(context, condition);
|
||||||
fold_expr(if_true);
|
fold_expr(context, if_true);
|
||||||
fold_expr(if_false);
|
fold_expr(context, if_false);
|
||||||
}
|
}
|
||||||
ast::Expr::If {
|
ast::Expr::If {
|
||||||
ref mut condition,
|
ref mut condition,
|
||||||
ref mut if_true,
|
ref mut if_true,
|
||||||
ref mut if_false,
|
ref mut if_false,
|
||||||
} => {
|
} => {
|
||||||
fold_expr(condition);
|
fold_expr(context, condition);
|
||||||
fold_expr(if_true);
|
fold_expr(context, if_true);
|
||||||
if let Some(ref mut if_false) = if_false {
|
if let Some(ref mut if_false) = if_false {
|
||||||
fold_expr(if_false);
|
fold_expr(context, if_false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Expr::Return {
|
ast::Expr::Return {
|
||||||
value: Some(ref mut value),
|
value: Some(ref mut value),
|
||||||
} => fold_expr(value),
|
} => fold_expr(context, value),
|
||||||
ast::Expr::Return { value: None } => (),
|
ast::Expr::Return { value: None } => (),
|
||||||
ast::Expr::First {
|
ast::Expr::First {
|
||||||
ref mut value,
|
ref mut value,
|
||||||
ref mut drop,
|
ref mut drop,
|
||||||
} => {
|
} => {
|
||||||
fold_expr(value);
|
fold_expr(context, value);
|
||||||
fold_expr(drop);
|
fold_expr(context, drop);
|
||||||
}
|
}
|
||||||
ast::Expr::Error => unreachable!(),
|
ast::Expr::Error => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/lib.rs
18
src/lib.rs
@@ -1,7 +1,7 @@
|
|||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
|
use parser::Sources;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use parser::Sources;
|
|
||||||
|
|
||||||
mod ast;
|
mod ast;
|
||||||
mod constfold;
|
mod constfold;
|
||||||
@@ -36,15 +36,18 @@ pub fn compile_file<P: AsRef<Path>>(path: P, options: Options) -> Result<Vec<u8>
|
|||||||
Ok(script) => script,
|
Ok(script) => script,
|
||||||
Err(_) => bail!("Parse failed"),
|
Err(_) => bail!("Parse failed"),
|
||||||
};
|
};
|
||||||
|
|
||||||
includes::resolve_includes(&mut new_script, &path)?;
|
includes::resolve_includes(&mut new_script, &path)?;
|
||||||
|
|
||||||
for include in std::mem::take(&mut new_script.includes) {
|
for include in std::mem::take(&mut new_script.includes) {
|
||||||
let mut path = path.parent().expect("Script path has no parent").to_path_buf();
|
let mut path = path
|
||||||
|
.parent()
|
||||||
|
.expect("Script path has no parent")
|
||||||
|
.to_path_buf();
|
||||||
path.push(include.path);
|
path.push(include.path);
|
||||||
pending_files.push((path, Some(include.span)));
|
pending_files.push((path, Some(include.span)));
|
||||||
}
|
}
|
||||||
|
|
||||||
script.merge(new_script);
|
script.merge(new_script);
|
||||||
}
|
}
|
||||||
Ok((_, false)) => (), // already parsed this include
|
Ok((_, false)) => (), // already parsed this include
|
||||||
@@ -59,8 +62,9 @@ pub fn compile_file<P: AsRef<Path>>(path: P, options: Options) -> Result<Vec<u8>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if constfold::fold_script(&mut script, &sources).is_err() {
|
||||||
constfold::fold_script(&mut script);
|
bail!("Constant folding failed");
|
||||||
|
}
|
||||||
if typecheck::tc_script(&mut script, &sources).is_err() {
|
if typecheck::tc_script(&mut script, &sources).is_err() {
|
||||||
bail!("Type check failed");
|
bail!("Type check failed");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -925,6 +925,21 @@ fn script_parser() -> impl Parser<Token, ast::Script, Error = ScriptError> + Clo
|
|||||||
})
|
})
|
||||||
.boxed();
|
.boxed();
|
||||||
|
|
||||||
|
let global_const = just(Token::Ident("const".to_string()))
|
||||||
|
.ignore_then(identifier)
|
||||||
|
.then(just(Token::Ctrl(':')).ignore_then(type_parser()).or_not())
|
||||||
|
.then(just(Token::Op("=".to_string())).ignore_then(expression.clone()))
|
||||||
|
.then_ignore(just(Token::Ctrl(';')))
|
||||||
|
.map_with_span(|((name, type_), value), span| {
|
||||||
|
ast::TopLevelItem::Const(ast::GlobalConst {
|
||||||
|
name,
|
||||||
|
type_,
|
||||||
|
value,
|
||||||
|
span,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.boxed();
|
||||||
|
|
||||||
let data_i8 = just(Token::Ident("i8".to_string()))
|
let data_i8 = just(Token::Ident("i8".to_string()))
|
||||||
.to(ast::DataType::I8)
|
.to(ast::DataType::I8)
|
||||||
.or(just(Token::Ident("i16".to_string())).to(ast::DataType::I16))
|
.or(just(Token::Ident("i16".to_string())).to(ast::DataType::I16))
|
||||||
@@ -975,17 +990,17 @@ fn script_parser() -> impl Parser<Token, ast::Script, Error = ScriptError> + Clo
|
|||||||
|path, span| ast::TopLevelItem::Include(ast::Include { span, path }),
|
|path, span| ast::TopLevelItem::Include(ast::Include { span, path }),
|
||||||
));
|
));
|
||||||
|
|
||||||
import.or(function).or(global).or(data).or(include).boxed()
|
import
|
||||||
|
.or(function)
|
||||||
|
.or(global)
|
||||||
|
.or(data)
|
||||||
|
.or(include)
|
||||||
|
.or(global_const)
|
||||||
|
.boxed()
|
||||||
};
|
};
|
||||||
|
|
||||||
top_level_item.repeated().then_ignore(end()).map(|items| {
|
top_level_item.repeated().then_ignore(end()).map(|items| {
|
||||||
let mut script = ast::Script {
|
let mut script = ast::Script::default();
|
||||||
imports: Vec::new(),
|
|
||||||
global_vars: Vec::new(),
|
|
||||||
functions: Vec::new(),
|
|
||||||
data: Vec::new(),
|
|
||||||
includes: Vec::new(),
|
|
||||||
};
|
|
||||||
for item in items {
|
for item in items {
|
||||||
match item {
|
match item {
|
||||||
ast::TopLevelItem::Import(i) => script.imports.push(i),
|
ast::TopLevelItem::Import(i) => script.imports.push(i),
|
||||||
@@ -993,6 +1008,7 @@ fn script_parser() -> impl Parser<Token, ast::Script, Error = ScriptError> + Clo
|
|||||||
ast::TopLevelItem::Function(f) => script.functions.push(f),
|
ast::TopLevelItem::Function(f) => script.functions.push(f),
|
||||||
ast::TopLevelItem::Data(d) => script.data.push(d),
|
ast::TopLevelItem::Data(d) => script.data.push(d),
|
||||||
ast::TopLevelItem::Include(i) => script.includes.push(i),
|
ast::TopLevelItem::Include(i) => script.includes.push(i),
|
||||||
|
ast::TopLevelItem::Const(c) => script.consts.push(c),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
script
|
script
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ impl LocalVars {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn report_duplicate_definition(
|
pub fn report_duplicate_definition(
|
||||||
msg: &str,
|
msg: &str,
|
||||||
span: &Span,
|
span: &Span,
|
||||||
prev_span: &Span,
|
prev_span: &Span,
|
||||||
|
|||||||
Reference in New Issue
Block a user