Skip to content

Commit

Permalink
added basic windows support (no stdlib)
Browse files Browse the repository at this point in the history
  • Loading branch information
Miezekatze64 committed Aug 29, 2022
1 parent 2b109ff commit 7c9b1f0
Show file tree
Hide file tree
Showing 8 changed files with 213 additions and 77 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
!swlc
!LICENSE
!build

*.exe

# Added by cargo
#
Expand Down
9 changes: 6 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use std::{fs, env::args, process::{exit, Command}, collections::HashMap,

/// Enum representing possible target types
// TODO(#2): parse target types (-t/--target)
#[derive(PartialEq, Eq)]
enum Target {
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
pub enum Target {
Linux,
#[allow(unused)]
Bsd,
Expand Down Expand Up @@ -161,7 +161,7 @@ fn main() {
// let (contents, links, links_libs) = preprocessor::preprocess(contents, filename.clone());

// construct parser
let mut parser = parser::Parser::new(contents, filename.clone(), verbose).unwrap_or_else(|a| {
let mut parser = parser::Parser::new(contents, filename.clone(), verbose, target).unwrap_or_else(|a| {
eprintln!("Error reading file: {}", a);
exit(1);
});
Expand Down Expand Up @@ -281,6 +281,9 @@ fn main() {

let mut outfile = path;
outfile.push_str(&name);
if target == Target::Windows {
outfile.push_str(".exe");
}

let mut linked_files = parser.links.clone();
let linked_libs = parser.linked_libs.clone();
Expand Down
10 changes: 6 additions & 4 deletions src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fs;

use crate::preprocessor;
use crate::{preprocessor, Target};

use {crate::{util, util::{indent, PrimitiveType, Type, BinaryOp, UnaryOp, ErrorLevel, Op, Error}, error}, std::{io, collections::HashMap}, crate::lexer::{TokenType, Lexer, Token}};

Expand All @@ -9,6 +9,7 @@ pub struct Parser {
pub lexer : Lexer,
pub links : Vec<String>,
pub linked_libs : Vec<String>,
pub target : Target,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -463,12 +464,13 @@ macro_rules! err_add {
}

impl Parser {
pub fn new(src: Vec<char>, filename: String, verbose: usize) -> Result<Self, io::Error> {
let (contents, l, ll) = preprocessor::preprocess(src, filename.clone());
pub fn new(src: Vec<char>, filename: String, verbose: usize, target: Target) -> Result<Self, io::Error> {
let (contents, l, ll) = preprocessor::preprocess(src, filename.clone(), target);
Ok(Parser {
lexer: Lexer::new(filename, contents, verbose)?,
links: l,
linked_libs: ll,
target,
})
}

Expand Down Expand Up @@ -1169,7 +1171,7 @@ impl Parser {
}

let contents = fs::read_to_string(filename.clone()).expect("File read error: ").chars().collect();
let mut file_parser = match Parser::new(contents, filename.clone(), verbose) {
let mut file_parser = match Parser::new(contents, filename.clone(), verbose, self.target) {
Ok(a) => a,
Err(e) => {
errors.push((ErrorLevel::Err, error!(self.lexer, token.pos, "ERROR during loading of file: {e}")));
Expand Down
69 changes: 61 additions & 8 deletions src/preprocessor.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{COLOR_RED, COLOR_GREEN, COLOR_RESET};
use crate::{COLOR_RED, COLOR_GREEN, COLOR_RESET, Target};
use std::process::exit;

fn pos_to_line_char(source: Vec<char>, pos: usize) -> (usize, usize) {
Expand Down Expand Up @@ -42,11 +42,18 @@ macro_rules! parse_str {
};
}

pub fn preprocess(file: Vec<char>, filename: String) -> (Vec<char>, Vec<String>, Vec<String>) {
#[derive(PartialEq, Eq)]
enum Action {
Delete,
Ignore
}

pub fn preprocess(file: Vec<char>, filename: String, tgt: Target) -> (Vec<char>, Vec<String>, Vec<String>) {
let mut i : usize = 0;
let mut to_skip : Vec<(usize, usize)> = vec![];
let mut links : Vec<String> = vec![];
let mut links_libs : Vec<String> = vec![];
let mut action_stack : Vec<(usize, Action)> = vec![];

while i < file.len() {
let ch = file[i];
Expand Down Expand Up @@ -75,9 +82,9 @@ pub fn preprocess(file: Vec<char>, filename: String) -> (Vec<char>, Vec<String>,
continue;
} else if ch == '#' {
let dir_start = i + 1;
while file[i] != ' ' {i += 1};
while !file[i].is_whitespace() {i += 1};
let directive = file.iter().skip(dir_start).take(i - dir_start).collect::<String>();
while file[i] != ' ' {i += 1};
while !file[i].is_whitespace() {i += 1};
to_skip.push((dir_start - 1, i - dir_start + 1));

match directive.as_str() {
Expand All @@ -103,14 +110,60 @@ pub fn preprocess(file: Vec<char>, filename: String) -> (Vec<char>, Vec<String>,
);
exit(1);
},
"target" => {
let target_ = match parse_str!(file, i, dir_start, filename) {
Some(a) => a,
None => continue,
};
let target = match target_.as_str() {
"linux" => Target::Linux,
"windows" => Target::Windows,
_ => {
let (l, c) = pos_to_line_char(file.clone(), dir_start);
eprintln!("{COLOR_RED}error: {COLOR_GREEN}{file}:{line}:{ch}: {COLOR_RESET}invalid target {target_}",
file = filename,
line = l+1,
ch = c+1,
);
exit(1);
}
};

if tgt != target {
action_stack.push((i+1, Action::Delete));
} else {
action_stack.push((i+1, Action::Ignore));
}
},
"end" => {
if action_stack.is_empty() {
let (l, c) = pos_to_line_char(file.clone(), dir_start);
eprintln!("{COLOR_RED}error: {COLOR_GREEN}{file}:{line}:{ch}: {COLOR_RESET}#end does not end anything",
file = filename,
line = l+1,
ch = c+1,
);
exit(1);
}
let (ind, action) = action_stack.pop().unwrap();
if action == Action::Delete {
for (v, item) in file.iter().enumerate().take(i).skip(ind) {
if *item != '\n' {
to_skip.push((v, 1));
}
}
}
}
_ => {
let (l, c) = pos_to_line_char(file.clone(), dir_start);
eprintln!("{file}:{line}:{ch}: Invalid preprocesser \
eprintln!("{COLOR_RED}error: {COLOR_GREEN}{file}:{line}:{ch}: {COLOR_RESET}Invalid preprocesser \
directive `{directive}`",
file = filename,
line = l+1,
ch = c+1,
)}
);
exit(1);
}
}
}
i += 1;
Expand All @@ -119,8 +172,8 @@ pub fn preprocess(file: Vec<char>, filename: String) -> (Vec<char>, Vec<String>,
to_skip.sort();
let mut new_file = file;
for (a, l) in to_skip.iter().rev() {
for _ in 0..*l {
new_file.remove(*a);
for i in 0..*l {
new_file[a+i] = ' ';
}
}

Expand Down
44 changes: 44 additions & 0 deletions swl/linux.swl
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,47 @@ func sleep(long millis) {
};
syscall2(35, as[long, ref time], 0l);
}


// runs a given command
// -----
// args:
// command <- the command
func system(string command) {
[char*] args = alloc_array(8*4);
args[0] = "/usr/bin/sh".to_cstr();
args[1] = "-c".to_cstr();
args[2] = command.to_cstr();
args[3] = as[char*, 0];

int pid = fork();
if (pid == 0) {
execve("/usr/bin/sh".to_cstr(), args, env());
exit(0);
}
while (true) {
long ret = syscall4(61, as[long, pid], 0l, 0l, 0l);
if (ret <= 0l) {
break;
}
sleep(10l);
}
}


// prints a given string to stdout
// ------
// args:
// str <- the string to print
func print([char] str) {
write(1l, arr2addr(str), arrlen(str));
}

// prints a given string to stderr
// ------
// args:
// str <- the string to print
func eprint([char] str) {
write(2l, arr2addr(str), arrlen(str));
}

84 changes: 23 additions & 61 deletions swl/std.swl
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/* SWL STANDARD LIBRARY */

#error "TODO"
#target "linux"
include "linux.swl";
#end

#target "windows"
include "windows.swl";
#end

// used intrinsics

Expand Down Expand Up @@ -172,6 +177,23 @@ func strcpy_off(string a, int a_off, string b, int b_off) {

/** IO UTILS **/

// prints a given string to stdout, followed by a line feed
// ------
// args:
// str <- the string to print
func println([char] str) {
print(str);
print("\n");
}

// prints a given string to stderr, followed by a line feed
// ------
// args:
// str <- the string to print
func eprintln([char] str) {
eprint(str);
eprint("\n");
}

func get_line([char] buf) -> int {
int bytes = 0;
Expand All @@ -198,66 +220,6 @@ func getch() -> char {
}
}

// prints a given string to stdout
// ------
// args:
// str <- the string to print
func print([char] str) {
write(1l, arr2addr(str), arrlen(str));
}

// prints a given string to stderr
// ------
// args:
// str <- the string to print
func eprint([char] str) {
write(2l, arr2addr(str), arrlen(str));
}

// prints a given string to stdout, followed by a line feed
// ------
// args:
// str <- the string to print
func println([char] str) {
print(str);
print("\n");
}

// prints a given string to stderr, followed by a line feed
// ------
// args:
// str <- the string to print
func eprintln([char] str) {
print(str);
print("\n");
}



// runs a given command
// -----
// args:
// command <- the command
func system(string command) {
[char*] args = alloc_array(8*4);
args[0] = "/usr/bin/sh".to_cstr();
args[1] = "-c".to_cstr();
args[2] = command.to_cstr();
args[3] = as[char*, 0];

int pid = fork();
if (pid == 0) {
execve("/usr/bin/sh".to_cstr(), args, env());
exit(0);
}
while (true) {
long ret = syscall4(61, as[long, pid], 0l, 0l, 0l);
if (ret <= 0l) {
break;
}
sleep(10l);
}
}

/** STRING UTILS **/

Expand Down
Loading

0 comments on commit 7c9b1f0

Please sign in to comment.