Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ pnpm-lock.yaml
go.mod
.RData
.Rhistory
program
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ CodeForge 是一款轻量级、高性能的桌面代码执行器,专为开发
<img src="public/icons/kotlin.svg" width="60" alt="Kotlin">
<img src="public/icons/lua.svg" width="60" alt="Lua">
<img src="public/icons/nodejs.svg" width="60" alt="Node.js">
<img src="public/icons/objective-c.svg" width="60" alt="Objective-C">
<img src="public/icons/objective-cpp.svg" width="60" alt="Objective-C++">
<img src="public/icons/php.svg" width="60" alt="PHP">
<img src="public/icons/python.svg" width="60" alt="Python 2">
<img src="public/icons/python.svg" width="60" alt="Python 3">
Expand Down
6 changes: 6 additions & 0 deletions public/icons/objective-c.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions public/icons/objective-cpp.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 73 additions & 0 deletions src-tauri/src/examples/objective-c.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
@autoreleasepool {
printf("🎉 欢迎使用 CodeForge!\n");
printf("Welcome to CodeForge!\n");
printf("\n");

printf("=========================================\n");
printf(" CodeForge Objective-C \n");
printf("=========================================\n");
printf("\n");

printf("✅ Objective-C运行成功! (Objective-C is working!)\n");
printf("⚡ 这是Objective-C程序 (This is Objective-C program)\n");
printf("\n");

int number1 = 10;
int number2 = 20;
int result = number1 + number2;

printf("🔢 简单计算 (Simple calculation):\n");
printf("%d + %d = %d\n", number1, number2, result);
printf("\n");

printf("📝 字符串操作 (String operations):\n");
printf("平台名称 (Platform): CodeForge\n");
printf("语言版本 (Language): Objective-C\n");
printf("完整信息 (Full info): CodeForge - Objective-C\n");
printf("\n");

printf("🍎 数组示例 (Array example):\n");
NSArray *fruits = @[@"苹果", @"香蕉", @"橙子", @"葡萄"];
for (int i = 0; i < fruits.count; i++) {
printf("%d. %s\n", i + 1, [fruits[i] UTF8String]);
}
printf("\n");

int score = 85;
printf("📊 成绩评估 (Score evaluation):\n");
if (score >= 90) {
printf("优秀! (Excellent!)\n");
} else if (score >= 80) {
printf("良好! (Good!)\n");
} else if (score >= 60) {
printf("及格 (Pass)\n");
} else {
printf("需要努力 (Need improvement)\n");
}
printf("\n");

printf("🔄 循环输出 (Loop output):\n");
for (int i = 1; i <= 5; i++) {
printf("第 %d 次输出 (Output #%d): Hello from CodeForge!\n", i, i);
}
printf("\n");

printf("🔁 While循环示例 (While loop example):\n");
int counter = 1;
while (counter <= 3) {
printf("While循环: 第 %d 次\n", counter);
counter++;
}
printf("\n");

printf("🎯 CodeForge Objective-C代码执行完成!\n");
printf("🎯 CodeForge Objective-C execution completed!\n");
printf("\n");
printf("感谢使用 CodeForge 代码执行环境! 🚀\n");
printf("Thank you for using CodeForge! 🚀\n");
}
return 0;
}
85 changes: 85 additions & 0 deletions src-tauri/src/examples/objective-cpp.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#import <Foundation/Foundation.h>
#include <iostream>
#include <vector>
#include <string>

int main(int argc, const char * argv[]) {
@autoreleasepool {
printf("🎉 欢迎使用 CodeForge!\n");
printf("Welcome to CodeForge!\n");
printf("\n");

printf("=========================================\n");
printf(" CodeForge Objective-C++ \n");
printf("=========================================\n");
printf("\n");

printf("✅ Objective-C++运行成功! (Objective-C++ is working!)\n");
printf("⚡ 这是Objective-C++程序 (This is Objective-C++ program)\n");
printf("\n");

int number1 = 10;
int number2 = 20;
int result = number1 + number2;

printf("🔢 简单计算 (Simple calculation):\n");
printf("%d + %d = %d\n", number1, number2, result);
printf("\n");

printf("📝 字符串操作 (String operations):\n");
std::string cppName = "CodeForge";
std::string cppVersion = "Objective-C++";
printf("平台名称 (Platform): %s\n", cppName.c_str());
printf("语言版本 (Language): %s\n", cppVersion.c_str());
printf("完整信息 (Full info): %s - %s\n", cppName.c_str(), cppVersion.c_str());
printf("\n");

printf("🍎 数组示例 (Array example - Objective-C):\n");
NSArray *fruits = @[@"苹果", @"香蕉", @"橙子", @"葡萄"];
for (int i = 0; i < fruits.count; i++) {
printf("%d. %s\n", i + 1, [fruits[i] UTF8String]);
}
printf("\n");

printf("🍇 Vector示例 (Vector example - C++):\n");
std::vector<std::string> colors = {"红色", "蓝色", "绿色", "黄色"};
for (size_t i = 0; i < colors.size(); i++) {
printf("%zu. %s\n", i + 1, colors[i].c_str());
}
printf("\n");

int score = 85;
printf("📊 成绩评估 (Score evaluation):\n");
if (score >= 90) {
printf("优秀! (Excellent!)\n");
} else if (score >= 80) {
printf("良好! (Good!)\n");
} else if (score >= 60) {
printf("及格 (Pass)\n");
} else {
printf("需要努力 (Need improvement)\n");
}
printf("\n");

printf("🔄 循环输出 (Loop output):\n");
for (int i = 1; i <= 5; i++) {
printf("第 %d 次输出 (Output #%d): Hello from CodeForge!\n", i, i);
}
printf("\n");

printf("🔁 While循环示例 (While loop example):\n");
int counter = 1;
while (counter <= 3) {
printf("While循环: 第 %d 次\n", counter);
counter++;
}
printf("\n");

printf("🎯 CodeForge Objective-C++代码执行完成!\n");
printf("🎯 CodeForge Objective-C++ execution completed!\n");
printf("\n");
printf("感谢使用 CodeForge 代码执行环境! 🚀\n");
printf("Thank you for using CodeForge! 🚀\n");
}
return 0;
}
48 changes: 42 additions & 6 deletions src-tauri/src/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
use crate::plugins::{LanguageInfo, PluginManager};
use log::{debug, error, info};
use regex::Regex;
use std::process::Command;
use tauri::State;
use tokio::sync::Mutex;

pub type PluginManagerState = Mutex<PluginManager>;

// 通用的环境信息获取函数
fn extract_version(output: &str) -> String {
let output = output.trim();

let version_patterns = vec![
r"(?i)version\s+([0-9]+\.[0-9]+\.[0-9]+(?:-[a-zA-Z0-9]+)?)",
r"(?i)version\s+([0-9]+\.[0-9]+(?:\.[0-9]+)?)",
r"\bv?([0-9]+\.[0-9]+\.[0-9]+(?:-[a-zA-Z0-9]+)?)\b",
r"\bv?([0-9]+\.[0-9]+(?:\.[0-9]+)?)\b",
r#""([0-9]+\.[0-9]+\.[0-9]+)""#,
];

for pattern in version_patterns {
if let Ok(re) = Regex::new(pattern) {
if let Some(cap) = re.captures(output) {
if let Some(version) = cap.get(1) {
return version.as_str().to_string();
}
}
}
}

if let Some(first_line) = output.lines().next() {
if !first_line.is_empty() {
return first_line.to_string();
}
}

output.to_string()
}

#[tauri::command]
pub async fn get_info(
language: String,
Expand Down Expand Up @@ -44,20 +74,27 @@ pub async fn get_info(
.arg(plugin.get_path_command())
.output();

let mut version = String::from_utf8_lossy(&version_out.stdout)
let mut raw_version = String::from_utf8_lossy(&version_out.stdout)
.trim()
.to_string();

if version.is_empty() {
if raw_version.is_empty() {
info!(
"获取环境 -> 调用插件 [ {} ] 版本为空,通过 stderr 获取",
language
);
version = String::from_utf8_lossy(&version_out.stderr)
raw_version = String::from_utf8_lossy(&version_out.stderr)
.trim()
.to_string();
}

let version = extract_version(&raw_version);
let final_version = if version.is_empty() {
raw_version
} else {
version
};

let path = if let Ok(path_out) = path_result {
if path_out.status.success() {
String::from_utf8_lossy(&path_out.stdout).trim().to_string()
Expand All @@ -71,7 +108,7 @@ pub async fn get_info(
info!("获取环境 -> 调用插件 [ {} ] 完成", language);
return Ok(LanguageInfo {
installed: true,
version,
version: final_version,
path,
language: plugin.get_language_name().to_string(),
});
Expand All @@ -90,7 +127,6 @@ pub async fn get_info(
})
}

// 获取支持的语言列表
#[tauri::command]
pub async fn get_supported_languages(
plugin_manager: State<'_, PluginManagerState>,
Expand Down
4 changes: 4 additions & 0 deletions src-tauri/src/plugins/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ use crate::plugins::javascript_nodejs::JavaScriptNodeJsPlugin;
use crate::plugins::kotlin::KotlinPlugin;
use crate::plugins::lua::LuaPlugin;
use crate::plugins::nodejs::NodeJSPlugin;
use crate::plugins::objective_c::ObjectiveCPlugin;
use crate::plugins::objective_cpp::ObjectiveCppPlugin;
use crate::plugins::php::PHPPlugin;
use crate::plugins::python2::Python2Plugin;
use crate::plugins::python3::Python3Plugin;
Expand Down Expand Up @@ -64,6 +66,8 @@ impl PluginManager {
plugins.insert("cangjie".to_string(), Box::new(CangjiePlugin));
plugins.insert("haskell".to_string(), Box::new(HaskellPlugin));
plugins.insert("lua".to_string(), Box::new(LuaPlugin));
plugins.insert("objective-c".to_string(), Box::new(ObjectiveCPlugin));
plugins.insert("objective-cpp".to_string(), Box::new(ObjectiveCppPlugin));
plugins.insert(
"javascript-nodejs".to_string(),
Box::new(JavaScriptNodeJsPlugin),
Expand Down
2 changes: 2 additions & 0 deletions src-tauri/src/plugins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,8 @@ pub mod kotlin;
pub mod lua;
pub mod manager;
pub mod nodejs;
pub mod objective_c;
pub mod objective_cpp;
pub mod php;
pub mod python2;
pub mod python3;
Expand Down
85 changes: 85 additions & 0 deletions src-tauri/src/plugins/objective_c.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
use super::{LanguagePlugin, PluginConfig};
use std::vec;

pub struct ObjectiveCPlugin;

impl LanguagePlugin for ObjectiveCPlugin {
fn get_order(&self) -> i32 {
27
}

fn get_language_name(&self) -> &'static str {
"Objective-C"
}

fn get_language_key(&self) -> &'static str {
"objective-c"
}

fn get_file_extension(&self) -> String {
self.get_config()
.map(|config| config.extension.clone())
.unwrap_or_else(|| "m".to_string())
}

fn get_version_args(&self) -> Vec<&'static str> {
vec!["--version"]
}

fn get_path_command(&self) -> String {
"which clang".to_string()
}

fn get_command(
&self,
_file_path: Option<&str>,
_is_version: bool,
_file_name: Option<String>,
) -> String {
if _is_version {
let clang_command = if self.get_execute_home().is_some() {
"./clang"
} else {
"clang"
};

return clang_command.to_string();
}

if let Some(config) = self.get_config() {
if let Some(run_cmd) = &config.run_command {
return if let Some(file_name) = _file_name {
run_cmd.replace("$filename", &file_name)
} else {
run_cmd.clone()
};
}
}
self.get_default_command()
}

fn get_default_config(&self) -> PluginConfig {
PluginConfig {
enabled: true,
language: String::from("objective-c"),
before_compile: Some(String::from(
"clang -framework Foundation $filename -o program",
)),
extension: String::from("m"),
execute_home: None,
run_command: Some(String::from("./program")),
after_compile: Some(String::from("rm -f program")),
template: Some(String::from(
"// Objective-C 示例代码 - CodeForge 代码执行环境\n\n",
)),
timeout: Some(30),
console_type: Some(String::from("console")),
}
}

fn get_default_command(&self) -> String {
self.get_config()
.and_then(|config| config.run_command.clone())
.unwrap_or_else(|| "./program".to_string())
}
}
Loading
Loading