# HG changeset patch
# User Windel Bouwman
# Date 1400354260 -7200
# Node ID 6ae782a085e0a3fa21a3f36affc6fe92cd7c0b75
# Parent bb4289c84907d6c53d24c4c3dfab916aa076f233
Added init program
diff -r bb4289c84907 -r 6ae782a085e0 kernel/build.xml
--- a/kernel/build.xml Fri May 16 13:05:10 2014 +0200
+++ b/kernel/build.xml Sat May 17 21:17:40 2014 +0200
@@ -4,18 +4,32 @@
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff -r bb4289c84907 -r 6ae782a085e0 kernel/src/kernel.c3
--- a/kernel/src/kernel.c3 Fri May 16 13:05:10 2014 +0200
+++ b/kernel/src/kernel.c3 Sat May 17 21:17:40 2014 +0200
@@ -6,6 +6,9 @@
import arch;
import io;
+// Globals:
+var process.process_t* init_proc;
+
// Main entry point of the kernel:
function void start()
@@ -13,15 +16,20 @@
io.println("Welcome to lcfos!");
arch.init();
-
- // process.init();
+ process.init();
memory.init();
- //Process proc = new process:Process();
+ init_proc = process.Create();
+
+ // TODO: copy content into process??
+ // Create a second process:
+ process.Create();
+
+ io.print2("init address ", cast(init_proc));
//scheduler:queue(proc);
io.println("Kernel finished");
- arch.halt();
+ panic();
}
// Called in total stress:
diff -r bb4289c84907 -r 6ae782a085e0 kernel/src/memory.c3
--- a/kernel/src/memory.c3 Fri May 16 13:05:10 2014 +0200
+++ b/kernel/src/memory.c3 Sat May 17 21:17:40 2014 +0200
@@ -5,17 +5,33 @@
var int ptr;
+// Let the heap grow upwards..
+
function void init()
{
- ptr = 0;
- // io.print2("ptr = ", ptr);
- // TODO
+ ptr = 0x80000;
}
-function u8* Alloc(int size)
+function u8* alloc(int size)
{
+ var int ptr2;
+ ptr2 = ptr;
+
+ io.print2("alloc size ", size);
+ io.print2("alloc address ", ptr);
+
+ // Increment new free point:
ptr = ptr + size;
- return cast(ptr);
+ return cast(ptr2);
}
+function void memcpy(u8* dst, u8* src, int size)
+{
+ //
+ var int i;
+ for (i = 0; i < size; i = i + 1)
+ {
+ *(dst + i) = *(src + i);
+ }
+}
diff -r bb4289c84907 -r 6ae782a085e0 kernel/src/process.c3
--- a/kernel/src/process.c3 Fri May 16 13:05:10 2014 +0200
+++ b/kernel/src/process.c3 Sat May 17 21:17:40 2014 +0200
@@ -15,6 +15,7 @@
// init is the root of all processes:
var process_t* root_process;
+
var int next_pid;
function void init()
@@ -30,10 +31,10 @@
function process_t* Create()
{
var process_t* p;
- //TODO: implement alloc:
- //= memory.Alloc(sizeof(process_t));
+ p = cast(memory.alloc(sizeof(process_t)));
p->id = next_pid;
+ p->status = 0; // Ready!
p->next = cast(0);
// Increment PID:
@@ -52,14 +53,13 @@
{
parent = parent->next;
}
+
parent->next = p;
}
return p;
}
-// function
-
function void Kill(process_t* p)
{
diff -r bb4289c84907 -r 6ae782a085e0 kernel/src/schedule.c3
--- a/kernel/src/schedule.c3 Fri May 16 13:05:10 2014 +0200
+++ b/kernel/src/schedule.c3 Sat May 17 21:17:40 2014 +0200
@@ -2,6 +2,7 @@
module scheduler;
import process;
+import arch;
var process.process_t *current;
diff -r bb4289c84907 -r 6ae782a085e0 kernel/src/syscall.c3
--- a/kernel/src/syscall.c3 Fri May 16 13:05:10 2014 +0200
+++ b/kernel/src/syscall.c3 Sat May 17 21:17:40 2014 +0200
@@ -9,6 +9,8 @@
import process;
+/* System call numbers:
+*/
const int SendMsg = 1;
const int ReceiveMsg = 2;
const int Reboot = 3;
@@ -18,7 +20,7 @@
function void handle_system_call(int callId, int a, int b)
{
// Main entry, check what to do here
- if (callId == 1)
+ if (callId == SendMsg)
{
handle_send_msg();
var process.process_t* proc;
diff -r bb4289c84907 -r 6ae782a085e0 python/ppci/buildfunctions.py
--- a/python/ppci/buildfunctions.py Fri May 16 13:05:10 2014 +0200
+++ b/python/ppci/buildfunctions.py Sat May 17 21:17:40 2014 +0200
@@ -16,8 +16,9 @@
from .target.target_list import targets
from .outstream import BinaryAndLoggingStream
from .objectfile import ObjectFile, load_object
-from . import DiagnosticsManager, CompilerError
-from .tasks import TaskError
+from . import DiagnosticsManager
+from .tasks import TaskError, TaskRunner
+from .recipe import RecipeLoader
def fix_target(tg):
@@ -64,6 +65,23 @@
raise TaskError('Cannot use {} as layout'.format(l))
+def construct(buildfile, targets=[]):
+ recipe_loader = RecipeLoader()
+ try:
+ project = recipe_loader.load_file(buildfile)
+ except OSError:
+ raise TaskError('Could not construct {}'.format(buildfile))
+ project = None
+
+ if project:
+ runner = TaskRunner()
+ res = runner.run(project, targets)
+ else:
+ res = 1
+
+ return res
+
+
def assemble(source, target):
""" Invoke the assembler on the given source, returns an object containing
the output. """
@@ -100,7 +118,7 @@
# Something went wrong, do not continue the code generation
continue
- d = {'ircode':ircode}
+ d = {'ircode': ircode}
logger.debug('Verifying code {}'.format(ircode), extra=d)
Verifier().verify(ircode)
@@ -113,7 +131,7 @@
Verifier().verify(ircode)
# Code generation:
- d = {'ircode':ircode}
+ d = {'ircode': ircode}
logger.debug('Starting code generation for {}'.format(ircode), extra=d)
cg.generate(ircode, output_stream)
@@ -132,4 +150,3 @@
linker = Linker(target)
output_obj = linker.link(objects, layout)
return output_obj
-
diff -r bb4289c84907 -r 6ae782a085e0 python/ppci/buildtasks.py
--- a/python/ppci/buildtasks.py Fri May 16 13:05:10 2014 +0200
+++ b/python/ppci/buildtasks.py Sat May 17 21:17:40 2014 +0200
@@ -4,10 +4,8 @@
Task can depend upon one another.
"""
-import logging
-
from .tasks import Task, TaskError, register_task
-from .buildfunctions import c3compile, link, assemble, fix_object
+from .buildfunctions import c3compile, link, assemble, fix_object, construct
from pyyacc import ParserException
from . import CompilerError
@@ -36,9 +34,17 @@
self.target.project.set_property(name, value)
+@register_task("build")
+class ConstructTask(Task):
+ """ Builds another build description file (build.xml) """
+ def run(self):
+ project = self.get_argument('file')
+ construct(project)
+
+
@register_task("assemble")
class AssembleTask(Task):
- """ Task that can runs the assembler over the source and enters the
+ """ Task that can runs the assembler over the source and enters the
output into an object file """
def run(self):
@@ -73,8 +79,8 @@
output = c3compile(sources, includes, target)
# Store output:
- with open(output_filename, 'w') as f:
- output.save(f)
+ with open(output_filename, 'w') as output_file:
+ output.save(output_file)
@register_task("link")
@@ -92,8 +98,8 @@
raise TaskError(e.msg)
# Store output:
- with open(output_filename, 'w') as f:
- output_obj.save(f)
+ with open(output_filename, 'w') as output_file:
+ output_obj.save(output_file)
@register_task("objcopy")
@@ -105,6 +111,5 @@
obj = fix_object(object_filename)
image = obj.get_image(image_name)
- with open(output_filename, 'wb') as f:
- f.write(image)
-
+ with open(output_filename, 'wb') as output_file:
+ output_file.write(image)
diff -r bb4289c84907 -r 6ae782a085e0 python/ppci/c3/astnodes.py
--- a/python/ppci/c3/astnodes.py Fri May 16 13:05:10 2014 +0200
+++ b/python/ppci/c3/astnodes.py Sat May 17 21:17:40 2014 +0200
@@ -207,6 +207,12 @@
self.loc = loc
+class Sizeof(Expression):
+ def __init__(self, typ, loc):
+ super().__init__(loc)
+ self.query_typ = typ
+
+
class Deref(Expression):
def __init__(self, ptr, loc):
super().__init__(loc)
@@ -380,6 +386,15 @@
return 'IF-statement'
+class Switch(Statement):
+ def __init__(self, condition, loc):
+ super().__init__(loc)
+ self.condition = condition
+
+ def __repr__(self):
+ return 'Switch on {}'.format(self.condition)
+
+
class While(Statement):
def __init__(self, condition, statement, loc):
super().__init__(loc)
diff -r bb4289c84907 -r 6ae782a085e0 python/ppci/c3/codegenerator.py
--- a/python/ppci/c3/codegenerator.py Fri May 16 13:05:10 2014 +0200
+++ b/python/ppci/c3/codegenerator.py Sat May 17 21:17:40 2014 +0200
@@ -113,8 +113,8 @@
elif type(code) is ast.Empty:
pass
elif type(code) is ast.Assignment:
- lval = self.genExprCode(code.lval)
- rval = self.genExprCode(code.rval)
+ lval = self.gen_expr_code(code.lval)
+ rval = self.gen_expr_code(code.rval)
if not self.equal_types(code.lval.typ, code.rval.typ):
raise SemanticError('Cannot assign {} to {}'
.format(code.rval.typ, code.lval.typ),
@@ -124,7 +124,7 @@
code.lval.loc)
self.emit(ir.Move(lval, rval))
elif type(code) is ast.ExpressionStatement:
- self.emit(ir.Exp(self.genExprCode(code.ex)))
+ self.emit(ir.Exp(self.gen_expr_code(code.ex)))
elif type(code) is ast.If:
bbtrue = self.newBlock()
bbfalse = self.newBlock()
@@ -138,7 +138,7 @@
self.emit(ir.Jump(te))
self.setBlock(te)
elif type(code) is ast.Return:
- re = self.genExprCode(code.expr)
+ re = self.gen_expr_code(code.expr)
self.emit(ir.Move(self.fn.return_value, re))
self.emit(ir.Jump(self.fn.epiloog))
b = self.newBlock()
@@ -167,6 +167,8 @@
self.genCode(code.final)
self.emit(ir.Jump(bbtest))
self.setBlock(te)
+ elif type(code) is ast.Switch:
+ raise NotImplementedError('Unknown stmt {}'.format(code))
else:
raise NotImplementedError('Unknown stmt {}'.format(code))
@@ -193,8 +195,8 @@
if not self.equal_types(expr.b.typ, self.boolType):
raise SemanticError('Must be boolean', expr.b.loc)
elif expr.op in ['==', '>', '<', '!=', '<=', '>=']:
- ta = self.genExprCode(expr.a)
- tb = self.genExprCode(expr.b)
+ ta = self.gen_expr_code(expr.a)
+ tb = self.gen_expr_code(expr.b)
if not self.equal_types(expr.a.typ, expr.b.typ):
raise SemanticError('Types unequal {} != {}'
.format(expr.a.typ, expr.b.typ),
@@ -204,7 +206,7 @@
raise SemanticError('non-bool: {}'.format(expr.op), expr.loc)
expr.typ = self.boolType
elif type(expr) is ast.Literal:
- self.genExprCode(expr)
+ self.gen_expr_code(expr)
if expr.val:
self.emit(ir.Jump(bbtrue))
else:
@@ -216,17 +218,21 @@
if not self.equal_types(expr.typ, self.boolType):
self.error('Condition must be boolean', expr.loc)
- def genExprCode(self, expr):
+ def gen_expr_code(self, expr):
""" Generate code for an expression. Return the generated ir-value """
assert isinstance(expr, ast.Expression)
if type(expr) is ast.Binop:
expr.lvalue = False
if expr.op in ['+', '-', '*', '/', '<<', '>>', '|', '&']:
- ra = self.genExprCode(expr.a)
- rb = self.genExprCode(expr.b)
+ ra = self.gen_expr_code(expr.a)
+ rb = self.gen_expr_code(expr.b)
if self.equal_types(expr.a.typ, self.intType) and \
self.equal_types(expr.b.typ, self.intType):
expr.typ = expr.a.typ
+ elif self.equal_types(expr.b.typ, self.intType) and \
+ type(expr.a.typ) is ast.PointerType:
+ # Special case for pointer arithmatic TODO: coerce!
+ expr.typ = expr.a.typ
else:
raise SemanticError('Can only add integers', expr.loc)
else:
@@ -234,7 +240,7 @@
return ir.Binop(ra, expr.op, rb)
elif type(expr) is ast.Unop:
if expr.op == '&':
- ra = self.genExprCode(expr.a)
+ ra = self.gen_expr_code(expr.a)
expr.typ = ast.PointerType(expr.a.typ)
if not expr.a.lvalue:
raise SemanticError('No valid lvalue', expr.a.loc)
@@ -253,13 +259,13 @@
expr.lvalue = True
return ir.Mem(self.varMap[tg])
elif isinstance(tg, ast.Constant):
- c_val = self.genExprCode(tg.value)
+ c_val = self.gen_expr_code(tg.value)
return self.evalConst(c_val)
else:
raise NotImplementedError(str(tg))
elif type(expr) is ast.Deref:
# dereference pointer type:
- addr = self.genExprCode(expr.ptr)
+ addr = self.gen_expr_code(expr.ptr)
ptr_typ = self.the_type(expr.ptr.typ)
expr.lvalue = True
if type(ptr_typ) is ast.PointerType:
@@ -268,7 +274,7 @@
else:
raise SemanticError('Cannot deref non-pointer', expr.loc)
elif type(expr) is ast.Member:
- base = self.genExprCode(expr.base)
+ base = self.gen_expr_code(expr.base)
expr.lvalue = expr.base.lvalue
basetype = self.the_type(expr.base.typ)
if type(basetype) is ast.StructureType:
@@ -288,8 +294,8 @@
return ir.Mem(ir.Add(base.e, offset))
elif type(expr) is ast.Index:
""" Array indexing """
- base = self.genExprCode(expr.base)
- idx = self.genExprCode(expr.i)
+ base = self.gen_expr_code(expr.base)
+ idx = self.gen_expr_code(expr.i)
base_typ = self.the_type(expr.base.typ)
if not isinstance(base_typ, ast.ArrayType):
raise SemanticError('Cannot index non-array type {}'
@@ -325,6 +331,12 @@
return ir.Const(expr.val)
elif type(expr) is ast.TypeCast:
return self.gen_type_cast(expr)
+ elif type(expr) is ast.Sizeof:
+ # The type of this expression is int:
+ expr.typ = self.intType
+ self.check_type(expr.query_typ)
+ type_size = self.size_of(expr.query_typ)
+ return ir.Const(type_size)
elif type(expr) is ast.FunctionCall:
return self.gen_function_call(expr)
else:
@@ -338,7 +350,7 @@
def gen_type_cast(self, expr):
""" Generate code for type casting """
- ar = self.genExprCode(expr.a)
+ ar = self.gen_expr_code(expr.a)
from_type = self.the_type(expr.a.typ)
to_type = self.the_type(expr.to_type)
if isinstance(from_type, ast.PointerType) and \
@@ -364,7 +376,7 @@
def gen_function_call(self, expr):
""" Generate code for a function call """
# Evaluate the arguments:
- args = [self.genExprCode(e) for e in expr.args]
+ args = [self.gen_expr_code(e) for e in expr.args]
# Check arguments:
tg = self.resolveSymbol(expr.proc)
if type(tg) is not ast.Function:
diff -r bb4289c84907 -r 6ae782a085e0 python/ppci/c3/lexer.py
--- a/python/ppci/c3/lexer.py Fri May 16 13:05:10 2014 +0200
+++ b/python/ppci/c3/lexer.py Sat May 17 21:17:40 2014 +0200
@@ -8,8 +8,9 @@
keywords = ['and', 'or', 'not', 'true', 'false',
'else', 'if', 'while', 'for', 'return',
+ 'switch', 'case', 'default',
'function', 'var', 'type', 'const',
- 'struct', 'cast',
+ 'struct', 'cast', 'sizeof',
'import', 'module']
diff -r bb4289c84907 -r 6ae782a085e0 python/ppci/c3/parser.py
--- a/python/ppci/c3/parser.py Fri May 16 13:05:10 2014 +0200
+++ b/python/ppci/c3/parser.py Sat May 17 21:17:40 2014 +0200
@@ -5,7 +5,7 @@
from .astnodes import Return, While, If, Empty, For
from .astnodes import FunctionType, Function, FormalParameter
from .astnodes import StructureType, DefinedType, PointerType, ArrayType
-from .astnodes import Constant, Variable
+from .astnodes import Constant, Variable, Sizeof
from .astnodes import StructField, Deref, Index
from .astnodes import Package
from .astnodes import Identifier
@@ -227,6 +227,13 @@
no = self.Statement() if self.hasConsumed('else') else Empty()
return If(condition, yes, no, loc)
+ def parse_switch(self):
+ loc = self.Consume('switch').loc
+ self.Consume('(')
+ condition = self.Expression()
+ self.Consume(')')
+ return Switch(condition, loc)
+
def parseWhile(self):
loc = self.Consume('while').loc
self.Consume('(')
@@ -271,6 +278,8 @@
return self.parseWhile()
elif self.Peak == 'for':
return self.parse_for()
+ elif self.Peak == 'switch':
+ return self.parse_switch()
elif self.Peak == '{':
return self.parseCompound()
elif self.hasConsumed(';'):
@@ -376,9 +385,18 @@
ce = self.Expression()
self.Consume(')')
return TypeCast(t, ce, loc)
+ elif self.Peak == 'sizeof':
+ return self.sizeof_expression()
else:
return self.UnaryExpression()
+ def sizeof_expression(self):
+ loc = self.Consume('sizeof').loc
+ self.Consume('(')
+ typ = self.parse_type_spec()
+ self.Consume(')')
+ return Sizeof(typ, loc)
+
def UnaryExpression(self):
if self.Peak in ['&', '*']:
op = self.Consume(self.Peak)
diff -r bb4289c84907 -r 6ae782a085e0 python/ppci/c3/visitor.py
--- a/python/ppci/c3/visitor.py Fri May 16 13:05:10 2014 +0200
+++ b/python/ppci/c3/visitor.py Sat May 17 21:17:40 2014 +0200
@@ -60,6 +60,8 @@
elif type(node) is TypeCast:
self.do(node.a)
self.do(node.to_type)
+ elif type(node) is Sizeof:
+ self.do(node.query_typ)
elif type(node) is Member:
self.do(node.base)
elif type(node) is Index:
diff -r bb4289c84907 -r 6ae782a085e0 python/ppci/tasks.py
--- a/python/ppci/tasks.py Fri May 16 13:05:10 2014 +0200
+++ b/python/ppci/tasks.py Sat May 17 21:17:40 2014 +0200
@@ -25,7 +25,7 @@
class Project:
- """ A project contains a set of named targets that can depend upon
+ """ A project contains a set of named targets that can depend upon
eachother """
def __init__(self, name):
self.name = name
@@ -67,7 +67,8 @@
target = self.get_target(target_name)
for dep in target.dependencies:
if dep in state:
- raise TaskError('Dependency loop detected {} -> {}'.format(target_name, dep))
+ raise TaskError('Dependency loop detected {} -> {}'
+ .format(target_name, dep))
self.dfs(dep, state)
def check_target(self, target_name):
@@ -195,4 +196,3 @@
self.logger.error(str(e.msg))
return 1
return 0
-
diff -r bb4289c84907 -r 6ae782a085e0 python/zcc.py
--- a/python/zcc.py Fri May 16 13:05:10 2014 +0200
+++ b/python/zcc.py Sat May 17 21:17:40 2014 +0200
@@ -4,10 +4,9 @@
import argparse
import logging
-from ppci.tasks import TaskRunner
from ppci.report import RstFormatter
-from ppci.recipe import RecipeLoader
-import ppci.buildtasks # Include not used, but it registers build tasks.
+from ppci.buildfunctions import construct
+import ppci.buildtasks # Include not used, but it registers build tasks.
import ppci
@@ -48,14 +47,7 @@
fh.setFormatter(RstFormatter())
logging.getLogger().addHandler(fh)
- recipe_loader = RecipeLoader()
- try:
- project = recipe_loader.load_file(args.buildfile)
- except OSError as e:
- res = 1
-
- runner = TaskRunner()
- res = runner.run(project, args.targets)
+ res = construct(args.buildfile, args.targets)
if args.report:
logging.getLogger().removeHandler(fh)
diff -r bb4289c84907 -r 6ae782a085e0 test/testc3.py
--- a/test/testc3.py Fri May 16 13:05:10 2014 +0200
+++ b/test/testc3.py Sat May 17 21:17:40 2014 +0200
@@ -392,7 +392,7 @@
module testarray;
function void t()
{
- int c[20];
+ var int c[20];
}
"""
self.expectErrors(snippet, [7])
@@ -418,12 +418,48 @@
print(a);
print("Moi");
}
+
function void print(string a)
{
}
"""
self.expectOK(snippet)
+ def testSizeof1(self):
+ snippet = """
+ module testsizeof;
+
+ function void t()
+ {
+ var int a;
+ a = sizeof(int*);
+ }
+ """
+ self.expectOK(snippet)
+
+ def testSizeof2(self):
+ snippet = """
+ module testsizeof2;
+
+ function void t()
+ {
+ sizeof(int*) = 2;
+ }
+ """
+ self.expectErrors(snippet, [6])
+
+ @unittest.skip('TODO: Too hard')
+ def testWrongVarUse(self):
+ snippet = """
+ module testsizeof;
+
+ function void t()
+ {
+ int a = 1;
+ }
+ """
+ self.expectOK(snippet)
+
def testPointerType1(self):
snippet = """
module testpointer1;
@@ -494,6 +530,17 @@
"""
self.expectOK(snippet)
+ def testPointerArithmatic(self):
+ snippet = """
+ module testpointerarithmatic;
+ function void t()
+ {
+ var int* pa;
+ *(pa+2) = 2;
+ }
+ """
+ self.expectOK(snippet)
+
def testWrongCast(self):
snippet = """
module testptr_ir;
diff -r bb4289c84907 -r 6ae782a085e0 user/build.xml
--- a/user/build.xml Fri May 16 13:05:10 2014 +0200
+++ b/user/build.xml Sat May 17 21:17:40 2014 +0200
@@ -1,12 +1,32 @@
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r bb4289c84907 -r 6ae782a085e0 user/hello.c3
--- a/user/hello.c3 Fri May 16 13:05:10 2014 +0200
+++ b/user/hello.c3 Sat May 17 21:17:40 2014 +0200
@@ -7,6 +7,6 @@
function void start()
{
- lib.print(9); // 'Hello space');
+ lib.print("Hello space");
}
diff -r bb4289c84907 -r 6ae782a085e0 user/init.c3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/user/init.c3 Sat May 17 21:17:40 2014 +0200
@@ -0,0 +1,12 @@
+module init;
+import lib;
+
+/*
+Initial program run by the system.
+*/
+
+function void start()
+{
+ lib.print("Welcome to lcfos");
+}
+
diff -r bb4289c84907 -r 6ae782a085e0 user/lib.c3
--- a/user/lib.c3 Fri May 16 13:05:10 2014 +0200
+++ b/user/lib.c3 Sat May 17 21:17:40 2014 +0200
@@ -3,14 +3,31 @@
/*
Runtime library.
-
*/
-function void print(int txt)
+// Hack until something better exists:
+function void putc(int c)
+{
+ var int *UART0DR;
+ UART0DR = cast(0x109000); // UART0 DR register when remapped at 1MB
+ *UART0DR = c;
+}
+
+function void print(string txt)
{
// TODO
var ipc.Msg msg;
ipc.SendMessage(&msg);
+
+ // TBD: send text to putc or via send message??
+ var int i;
+ i = 0;
+
+ while (i < txt->len)
+ {
+ putc(cast(txt->txt[i]));
+ i = i + 1;
+ }
}